/*
 * MainScreen.java
 *
 * Created on 29 de Agosto de 2008, 10:10
 */

package gui;

import javax.swing.JOptionPane;
import javax.swing.JTextField;
import java.util.Vector;
import bean.MemoryCell;
import bean.Process;
import manager.MemoryGenerator;
import thread.AlgorithmStepsThread;

/**
 *
 * @author  Fabricio Reis
 */
public class MainScreen extends javax.swing.JApplet {
    
    // Definitions shown to the user when the applet starts
    final static String START_TEXT = "Seja bem vindo! \n Para começar a usar este software educativo clique em 'Introdução'.";
    final static int MEMORY_SIZE = 45; //This value must be multiple by 3 because are three rows of memory cells
    final static int FREE_SPACES_IN_THE_MEMORY = 20;
    final int MINIMUM_SIZE = 1; // These values ('MINIMUM_SIZE' e 'MAXIMUM_SIZE') define the possible values to size a process
    final int MAXIMUM_SIZE = 5;
    
    Vector<MemoryCell> mainMemory;  //This object stores the 'mainMemory' generated by some method 'createsRandomMemory' of the 'MemoryGenerator' class
    Vector<MemoryCell> finalMainMemory; //This object stores the 'mainMemory' after the method 'clusterFreeCells' of the 'MemoryGenerator' class
    MemoryGenerator memoryGenerator = new MemoryGenerator();
    Vector<Process> processesQueue = new Vector<Process>(); //This object stores the processes' size inserted by the user to be added into the 'finalMainMemory' (memory)
    
    int processCounter = 0; //This variable is used to label orderly the blocks in 'jPanelAnimation' (processes in the memory)
    int initialPositionBlocks = 0; //This variable stores the initial position that is used to paint the blocks in the jPanelAnimation
                                   //it's passed to the thread
    AlgorithmStepsThread st;
    Thread t;

    /** Initializes the applet MainScreen */    
    @Override
    public void init() {
        try {
            this.setSize(1009, 628);
            JOptionPane.showMessageDialog(null, START_TEXT, "", JOptionPane.INFORMATION_MESSAGE);
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents();
                    jPanelLegend.setVisible(false);
                    jPanelInsertion.setVisible(false);
                    jPanelProcessesQueue.setVisible(false);
                    jButtonOkNextStep.setVisible(false);
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }    
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelIntroduction = new javax.swing.JPanel();
        jScrollPaneIntroduction = new javax.swing.JScrollPane();
        jTextAreaIntroduction = new javax.swing.JTextArea();
        jPanelAlgorithm = new javax.swing.JPanel();
        jScrollPaneAlgorithm = new javax.swing.JScrollPane();
        jTextAreaAlgorithm = new javax.swing.JTextArea();
        jPanelAnimation = new javax.swing.JPanel();
        jPanelLegend = new javax.swing.JPanel();
        jTextFieldLegendFree = new javax.swing.JTextField();
        jTextFieldLegendBusy = new javax.swing.JTextField();
        jTextFieldLegendActiveProcess = new javax.swing.JTextField();
        jTextFieldLegendProcessInTheQueue = new javax.swing.JTextField();
        jTextFieldLegendJ = new javax.swing.JTextField();
        jPanelInsertion = new javax.swing.JPanel();
        jLabelProcessSize = new javax.swing.JLabel();
        jTextFieldProcessSize = new javax.swing.JTextField();
        jButtonInsertProcess = new javax.swing.JButton();
        jPanelProcessesQueue = new javax.swing.JPanel();
        jLabelIncreaseOrientation = new javax.swing.JLabel();
        jButtonIntroduction = new javax.swing.JButton();
        jButtonStart = new javax.swing.JButton();
        jButtonAlgorithmSteps = new javax.swing.JButton();
        jButtonRestart = new javax.swing.JButton();
        jButtonOkNextStep = new javax.swing.JButton();

        setBackground(new java.awt.Color(204, 204, 204));

        jPanelIntroduction.setBorder(javax.swing.BorderFactory.createTitledBorder("Introdução"));

        jTextAreaIntroduction.setColumns(20);
        jTextAreaIntroduction.setEditable(false);
        jTextAreaIntroduction.setFont(new java.awt.Font("Tahoma", 1, 12));
        jTextAreaIntroduction.setRows(5);
        jTextAreaIntroduction.setToolTipText("Aqui será exibida uma breve introdução da política tratada");
        jScrollPaneIntroduction.setViewportView(jTextAreaIntroduction);

        javax.swing.GroupLayout jPanelIntroductionLayout = new javax.swing.GroupLayout(jPanelIntroduction);
        jPanelIntroduction.setLayout(jPanelIntroductionLayout);
        jPanelIntroductionLayout.setHorizontalGroup(
            jPanelIntroductionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, 973, Short.MAX_VALUE)
        );
        jPanelIntroductionLayout.setVerticalGroup(
            jPanelIntroductionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, 87, Short.MAX_VALUE)
        );

        jPanelAlgorithm.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Algoritmo", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));

        jTextAreaAlgorithm.setColumns(20);
        jTextAreaAlgorithm.setEditable(false);
        jTextAreaAlgorithm.setFont(new java.awt.Font("Tahoma", 1, 12));
        jTextAreaAlgorithm.setRows(5);
        jTextAreaAlgorithm.setToolTipText("Aqui será exibido o algoritmo da política tratada");
        jScrollPaneAlgorithm.setViewportView(jTextAreaAlgorithm);

        javax.swing.GroupLayout jPanelAlgorithmLayout = new javax.swing.GroupLayout(jPanelAlgorithm);
        jPanelAlgorithm.setLayout(jPanelAlgorithmLayout);
        jPanelAlgorithmLayout.setHorizontalGroup(
            jPanelAlgorithmLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, 412, Short.MAX_VALUE)
        );
        jPanelAlgorithmLayout.setVerticalGroup(
            jPanelAlgorithmLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, 423, Short.MAX_VALUE)
        );

        jPanelAnimation.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Memória Principal", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelAnimation.setToolTipText("Aqui serão exibidas animações gráficas de inserções de processos na memória");

        javax.swing.GroupLayout jPanelAnimationLayout = new javax.swing.GroupLayout(jPanelAnimation);
        jPanelAnimation.setLayout(jPanelAnimationLayout);
        jPanelAnimationLayout.setHorizontalGroup(
            jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 539, Short.MAX_VALUE)
        );
        jPanelAnimationLayout.setVerticalGroup(
            jPanelAnimationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 185, Short.MAX_VALUE)
        );

        jPanelLegend.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Legenda", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelLegend.setToolTipText("Legendas");

        jTextFieldLegendFree.setBackground(new java.awt.Color(255, 255, 255));
        jTextFieldLegendFree.setEditable(false);
        jTextFieldLegendFree.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendFree.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendFree.setText("LIVRE");

        jTextFieldLegendBusy.setBackground(new java.awt.Color(255, 51, 0));
        jTextFieldLegendBusy.setEditable(false);
        jTextFieldLegendBusy.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendBusy.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendBusy.setText("OCUPADO");

        jTextFieldLegendActiveProcess.setBackground(new java.awt.Color(51, 255, 255));
        jTextFieldLegendActiveProcess.setEditable(false);
        jTextFieldLegendActiveProcess.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendActiveProcess.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendActiveProcess.setText("PROCESSO A SER INSERIDO");

        jTextFieldLegendProcessInTheQueue.setBackground(new java.awt.Color(0, 255, 0));
        jTextFieldLegendProcessInTheQueue.setEditable(false);
        jTextFieldLegendProcessInTheQueue.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendProcessInTheQueue.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendProcessInTheQueue.setText("PROCESSO NA FILA DE ENTRADA");

        jTextFieldLegendJ.setBackground(new java.awt.Color(255, 255, 102));
        jTextFieldLegendJ.setFont(new java.awt.Font("Tahoma", 1, 11));
        jTextFieldLegendJ.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextFieldLegendJ.setText("\"j\"");

        javax.swing.GroupLayout jPanelLegendLayout = new javax.swing.GroupLayout(jPanelLegend);
        jPanelLegend.setLayout(jPanelLegendLayout);
        jPanelLegendLayout.setHorizontalGroup(
            jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelLegendLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jTextFieldLegendFree, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldLegendBusy, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldLegendActiveProcess, javax.swing.GroupLayout.PREFERRED_SIZE, 166, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldLegendProcessInTheQueue, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldLegendJ, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        jPanelLegendLayout.setVerticalGroup(
            jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelLegendLayout.createSequentialGroup()
                .addGroup(jPanelLegendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldLegendFree, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldLegendBusy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldLegendActiveProcess, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldLegendProcessInTheQueue, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldLegendJ, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanelInsertion.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Inserção de Processos", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.TOP));
        jPanelInsertion.setToolTipText("Inserção de Processos");

        jLabelProcessSize.setText("Tamanho do Processo:");

        jTextFieldProcessSize.setToolTipText("Digite aqui o tamanho do processo a ser inserido");

        jButtonInsertProcess.setText("Inserir");
        jButtonInsertProcess.setToolTipText("Clique aqui para inserir o processo na fila de entrada");
        jButtonInsertProcess.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonInsertProcessActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelInsertionLayout = new javax.swing.GroupLayout(jPanelInsertion);
        jPanelInsertion.setLayout(jPanelInsertionLayout);
        jPanelInsertionLayout.setHorizontalGroup(
            jPanelInsertionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelInsertionLayout.createSequentialGroup()
                .addGap(57, 57, 57)
                .addComponent(jLabelProcessSize)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldProcessSize, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(39, 39, 39)
                .addComponent(jButtonInsertProcess)
                .addContainerGap(239, Short.MAX_VALUE))
        );
        jPanelInsertionLayout.setVerticalGroup(
            jPanelInsertionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelInsertionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addGroup(jPanelInsertionLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabelProcessSize)
                    .addComponent(jTextFieldProcessSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addComponent(jButtonInsertProcess))
        );

        jPanelProcessesQueue.setBorder(javax.swing.BorderFactory.createTitledBorder("Fila de Entrada de Processos"));
        jPanelProcessesQueue.setToolTipText("Fila de Entrada de Processos");

        jLabelIncreaseOrientation.setText("--> +");

        javax.swing.GroupLayout jPanelProcessesQueueLayout = new javax.swing.GroupLayout(jPanelProcessesQueue);
        jPanelProcessesQueue.setLayout(jPanelProcessesQueueLayout);
        jPanelProcessesQueueLayout.setHorizontalGroup(
            jPanelProcessesQueueLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProcessesQueueLayout.createSequentialGroup()
                .addComponent(jLabelIncreaseOrientation)
                .addContainerGap(242, Short.MAX_VALUE))
        );
        jPanelProcessesQueueLayout.setVerticalGroup(
            jPanelProcessesQueueLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelProcessesQueueLayout.createSequentialGroup()
                .addComponent(jLabelIncreaseOrientation)
                .addContainerGap(69, Short.MAX_VALUE))
        );

        jButtonIntroduction.setToolTipText("Clique aqui para ver o algoritmo e um resumo teórico da política tratada");
        jButtonIntroduction.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonIntroduction.setLabel("Introdução");
        jButtonIntroduction.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonIntroductionActionPerformed(evt);
            }
        });

        jButtonStart.setText("Iniciar");
        jButtonStart.setToolTipText("Clique aqui para inserir processos na memória");
        jButtonStart.setEnabled(false);
        jButtonStart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartActionPerformed(evt);
            }
        });

        jButtonAlgorithmSteps.setText("Passos do Algoritmo");
        jButtonAlgorithmSteps.setToolTipText("Clique aqui para adicionar e visualizar a animação gráfica de inserção do processo na memória");
        jButtonAlgorithmSteps.setEnabled(false);
        jButtonAlgorithmSteps.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonAlgorithmSteps.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAlgorithmStepsActionPerformed(evt);
            }
        });

        jButtonRestart.setText("Reiniciar");
        jButtonRestart.setToolTipText("Clique aqui para reiniciar o software");
        jButtonRestart.setEnabled(false);
        jButtonRestart.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonRestart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRestartActionPerformed(evt);
            }
        });

        jButtonOkNextStep.setFont(new java.awt.Font("Tahoma", 1, 12));
        jButtonOkNextStep.setText("Clique aqui para próximo passo");
        jButtonOkNextStep.setToolTipText("Clique aqui para próximo passo");
        jButtonOkNextStep.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanelIntroduction, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jPanelAlgorithm, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                        .addComponent(jPanelProcessesQueue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addGap(270, 270, 270))
                                    .addComponent(jPanelLegend, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(jPanelInsertion, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(jPanelAnimation, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(161, 161, 161)
                        .addComponent(jButtonIntroduction)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonStart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonAlgorithmSteps)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonRestart)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonOkNextStep)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanelIntroduction, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanelAnimation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(5, 5, 5)
                        .addComponent(jPanelLegend, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelInsertion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(5, 5, 5)
                        .addComponent(jPanelProcessesQueue, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(jPanelAlgorithm, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonIntroduction)
                    .addComponent(jButtonStart)
                    .addComponent(jButtonAlgorithmSteps)
                    .addComponent(jButtonRestart)
                    .addComponent(jButtonOkNextStep))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonIntroductionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonIntroductionActionPerformed
        final String TEXT_BASE_INTRODUCTION = "\n" +
                                              "Na multiprogramação, vários processos são executados simultaneamente por meio da divisão do tempo do processador. Para que a troca de\n" +
                                              "contexto entre os diferentes processos aconteça de forma eficiente, eles devem estar na memória principal do computador. Os sistemas\n" +
                                              "operacionais possuem um componente responsável por gerenciar a memória principal do computador.\n\n" +
                                              "* GERENCIADOR DE MEMÓRIA: é o componente do sistema operacional responsável por coordenar a hierarquia de memórias. Sua função é\n" +
                                              "manter os controle das partes da memória que estão e não estão em uso, alocando espaço para processos quando eles precisarem e\n" +
                                              "liberando quando eles terminam, além de gerenciar a troca de processos (swapping) entre a memória e o disco quando a memória principal\n" +
                                              "não é suficientemente grande para acomodar os processos. Este gerenciador deve manter na memória principal o maior número de processos\n" +
                                              "possíveis para garantir o compartilhamento dos recursos. Mesmo que não haja memória livre, o gerenciador deve permitir que novos\n" +
                                              "processos sejam aceitos na fila de entrada.\n\n" +
                                              "A memória principal de um computador deve ser considerada em termos de organização. Assim, várias questões podem ser levantadas quanto\n" +
                                              "às diferentes possibilidades e à organização da memória. Exemplos: i) a memória deve conter apenas um processo ou vários ao mesmo tempo\n" +
                                              "(multiprogramação)? ii) caso a memória tenha vários processos ao mesmo tempo, dividi-la igualmente para cada processo ou dividi-la em\n" +
                                              "partições de tamanhos diferentes? iii) exigir que processos executem em partições específicas ou em qualquer lugar onde couberem?\n" +
                                              "iv) permitir que o sistema coloque cada processo em blocos contíguos de endereçamento ou dividi-los em blocos separados?\n\n" +
                                              "Basicamente existem duas formas de gerência de memória relativas à multiprogramação que tentam responder tais questões:\n" +
                                              "multiprogramação por partição fixa e multiprogramação por partição variável.\n\n" +
                                              "* MULTIPROGRAMAÇÃO POR PARTIÇÃO FIXA: neste caso, a memória é dividida em duas partes, sendo uma para o sistema operacional e a outra\n" +
                                              "para os processos do usuário. Em seguida, a partição do usuário é dividida em várias outras partições de diferentes tamanhos, porém fixos.\n\n" +
                                              "* MULTIPROGRAMAÇÃO POR PARTIÇÃO VARIÁVEL: neste esquema de organização, a quantidade, o tamanho e a localização das partições variam\n" +
                                              "dinamicamente com o tempo, ou seja, à medida que os processos entram e saem da memória. Estas partições são ajustadas dinamicamente\n" +
                                              "às necessidades exatas de cada processo. Uma das principais vantagens desta estratégia em relação à multiprogramação por partições fixas\n" +
                                              "é a flexibilidade alcançada em aumentar muito o uso da memória, reduzindo o desperdício de espaço. Entretanto, esta gerência é mais\n" +
                                              "difícil e pode gerar fragmentação externa. Para isso, o sistema operacional mantém na memória uma lista de partições livres e a manipula\n" +
                                              "de acordo com a política implementada. Quando um processo chega e precisa de memória, o gerenciador de memória percorre a lista de\n" +
                                              "partições livres (seguindo a política implementada) em busca de uma partição suficientemente grande para esse processo. Caso a partição\n" +
                                              "encontrada seja muito grande, ela é dividida em duas partes na qual uma é destinada ao processo e a outra volta para a lista de lacunas\n" +
                                              "livres, assim como acontece quando um processo termina. Caso a partição liberada seja adjacente a uma partição livre, elas são agrupadas\n" +
                                              "para formar uma maior.\n\n" +
                                              "* Este software Educativo trata da política NEXT-FIT (o próximo que couber):\n" +
                                              "Também conhecida como CIRCULAR-FIT, esta política é muito semelhante à First-fit, diferindo na partição considerada para o início da busca,\n" +
                                              "pois ela continua a busca por uma partição livre partindo da posição que parou na última busca.\n\n" +
                                              "* VEJA O ALGORITMO ABAIXO.";
        final String TEXT_BASE_ALGORITHM = "* FUNÇÃO QUE ENCONTRA A POSIÇÃO INICIAL PARA AS CHAMADAS FUTURAS DA FUNÇÃO NEXT-FIT\n" +
                                           "* OBS.: NA PRIMEIRA CHAMADA, O VALOR DE 'posicaoInicial' É IGUAL A 0 (ZERO).\n" +
                                           "funcao encontraPosicaoNextFit (vetor<TAD_CelulaMemoria> memoria, TAD_Processo processo, inteiro posicaoInicial) : inteiro\n" +
                                           "inicio\n" +
                                           "     inteiro j, i;\n" +
                                           "     TAD_CelulaMemoria celula;\n" +
                                           "     booleano achou := falso;\n" +
                                           "     i := posicaoInicial;\n" +
                                           "     j := 0;\n\n" +
                                           "     enquanto (!achou) faca\n" +
                                           "          se (i <= (TAMANHO_memoria - 1))\n" +
                                           "               celula := memoria[i];\n" +
                                           "               se ((TAMANHO_processo <= TAMANHO_celula) e (celula está livre))\n" +
                                           "                    j := i;\n" +
                                           "                    achou := verdadeiro;\n" +
                                           "               Fim se\n" +
                                           "               i++;\n" +
                                           "          Fim se\n" +
                                           "          senao\n" +
                                           "               se ((i = TAMANHO_memoria) e (!achou))\n" +
                                           "                    se (posicaoInicial = 0)\n" +
                                           "                         achou := verdadeiro;\n" +
                                           "                         j := -1; // Este valor caracteriza que o algoritmo não encontrou solução\n" +
                                           "                    Fim se\n" +
                                           "                    senao\n" +
                                           "                         i := 0;\n" +
                                           "                         enquanto (!achou) faca\n" +
                                           "                              celula := memoria[i];\n" +
                                           "                              se ((TAMANHO_processo <= TAMANHO_celula) e (celula está livre))\n" +
                                           "                                   j := i;\n" +
                                           "                                   achou := verdadeiro;\n" +
                                           "                              Fim se\n" +
                                           "                              i++;\n" +
                                           "                              se ((i = posicaoInicial) e (!achou))\n" +
                                           "                                   achou := verdadeiro;\n" +
                                           "                                   j := -1; // Este valor caracteriza que o algoritmo não encontrou solução\n" +
                                           "                              Fim se\n" +
                                           "                         Fim enquanto\n" +
                                           "                    Fim senao\n" +
                                           "               Fim se\n" +
                                           "          Fim senao\n" +
                                           "     Fim enquanto\n" +
                                           "     encontraPosicaoNextFit := i;\n" +
                                           "fim.\n\n" +
                                           
                                           "* FUNÇÃO NEXT-FIT - RETORNA A MEMÓRIA (PASSADA COMO PARÂMETRO) COM O PROCESSO INSERIDO\n" +
                                           "* OBS.: NA PRIMEIRA CHAMADA, O VALOR DE 'posicaoInicial' É IGUAL A 0 (ZERO).\n" +
                                           "funcao nextFit (vetor<TAD_CelulaMemoria> memoria, TAD_Processo processo, inteiro posicaoInicial) : Vetor<TAD_CelulaMemoria>\n" +
                                           "inicio\n" +
                                           "     inteiro resto, j, i, sucesso;\n" +
                                           "     Vetor<TAD_CelulaMemoria> novaMemoria := memoria;\n" +
                                           "     TAD_CelulaMemoria celula;\n" +
                                           "     booleano achou := falso;\n" +
                                           "     i := posicaoInicial;\n" +
                                           "     j := 0;\n\n" +
                                           "     enquanto (!achou) faca\n" +
                                           "          se (i <= (TAMANHO_memoria - 1))\n" +
                                           "               celula := memoria[i];\n" +
                                           "               se ((TAMANHO_processo <= TAMANHO_celula) e (celula está livre))\n" +
                                           "                    resto := (TAMANHO_celula - TAMANHO_processo);\n" +
                                           "                    j := i;\n" +
                                           "                    achou := verdadeiro;\n" +
                                           "                    sucesso := 1;\n" +
                                           "               Fim se\n" +
                                           "               i++;\n" +
                                           "          Fim se\n" +
                                           "          senao\n" +
                                           "               se ((i = TAMANHO_memoria) e (!achou))\n" +
                                           "                    se (posicaoInicial = 0)\n" +
                                           "                         achou := verdadeiro;\n" +
                                           "                         j := -1; // Este valor caracteriza que o algoritmo não encontrou solução\n" +
                                           "                    Fim se\n" +
                                           "                    senao\n" +
                                           "                         i := 0;\n" +
                                           "                         enquanto (!achou) faca\n" +
                                           "                              celula := memoria[i];\n" +
                                           "                              se ((TAMANHO_processo <= TAMANHO_celula) e (celula está livre))\n" +
                                           "                                   resto := (TAMANHO_celula - TAMANHO_processo);\n" +
                                           "                                   j := i;\n" +
                                           "                                   achou := verdadeiro;\n" +
                                           "                                   sucesso := 1;\n" +
                                           "                              Fim se\n" +
                                           "                              i++;\n" +
                                           "                              se ((i = posicaoInicial) e (!achou))\n" +
                                           "                                   achou := verdadeiro;\n" +
                                           "                                   j := -1; // Este valor caracteriza que o algoritmo não encontrou solução\n" +
                                           "                              Fim se\n" +
                                           "                         Fim enquanto\n" +
                                           "                    Fim senao\n" +
                                           "               Fim se\n" +
                                           "          Fim senao\n" +
                                           "     Fim enquanto\n\n" +
                                           "     se (sucesso = 1)\n" +
                                           "          celula := processo;\n\n" +
                                           "          // Aqui é adicionada a célula(processo) na posição 'j' da memória\n" +
                                           "          // enquanto que os outros elementos da memória são deslocados uma posição para a direita\n" +
                                           "          novaMemoria[j] := celula;\n\n" +
                                           "          se (resto > 0)\n" +
                                           "               // Aqui é adicionada uma célula livre de tamanho igual a 'resto' na posição 'j + 1'\n" +
                                           "               // da memória enquanto que os outros elementos da memória são deslocados uma posição para a direita\n" +
                                           "               novaMemoria[j + 1] := celula_livre_de_tamanho_igual_a_'resto';\n" +
                                           "          Fim se\n" +
                                           "     Fim se\n" +
                                           "     nextFit := novaMemoria;\n" +
                                           "fim.";

        this.jTextAreaIntroduction.setText(TEXT_BASE_INTRODUCTION);
        this.jTextAreaAlgorithm.setText(TEXT_BASE_ALGORITHM);
        JOptionPane.showMessageDialog(null, "Após conferir o texto de introdução e o algoritmo tratado, \n" +
                "clique em 'Iniciar' para inserir processos na memória. \n", "DICA", JOptionPane.INFORMATION_MESSAGE);
        this.jButtonIntroduction.setEnabled(false);
        this.jButtonStart.setEnabled(true);
        this.jTextAreaIntroduction.setToolTipText("Introdução da política tratada");
        this.jTextAreaAlgorithm.setToolTipText("Algoritmo da política tratada");
    }//GEN-LAST:event_jButtonIntroductionActionPerformed

    private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartActionPerformed
        this.mainMemory = new Vector<MemoryCell>();
        this.mainMemory = this.memoryGenerator.createsRandomMemory(MEMORY_SIZE, FREE_SPACES_IN_THE_MEMORY);
        this.finalMainMemory = new Vector<MemoryCell>();
        this.finalMainMemory = memoryGenerator.clusterFreeCells(mainMemory);

        for(int i = 0; i <= (this.finalMainMemory.size() - 1); i++) {
            if(!this.finalMainMemory.elementAt(i).isIsFree()){
                this.processCounter = this.finalMainMemory.elementAt(i).getProcess().getId();
            }
        }

        this.paintMainMemory(this.finalMainMemory);
        this.jPanelLegend.setVisible(true);
        this.jPanelInsertion.setVisible(true);
        this.jPanelProcessesQueue.setVisible(true);
        JOptionPane.showMessageDialog(null, "Para inserir um processo na memória, digite seu tamanho e clique em 'Inserir'.\n" +
                "OBSERVAÇÕES: 1) São permitidos somente valores inteiros entre " + MINIMUM_SIZE + " e " + MAXIMUM_SIZE + ";\n" +
                "                                2) Foi gerada aleatoriamente uma memória para ser usada na simulação;\n" +
                "                                3) Inicialmente a memória contém " + this.memoryGenerator.counterOfFreeSpaces(this.finalMainMemory) + " células livres; \n" +                    
                "                                4) Os processos recebem tempos de vida aleatórios;\n" +
                "                                5) A cada inserção os tempos de vida dos processos da memória principal são reduzidos em uma unidade;\n" +
                "                                6) Antes de ir para a memória principal o processo passa pela fila de entrada de processos;\n" +
                "                                7) Passe o cursor do mouse sobre os processos na memória principal (Blocos Vermelhos) para ver seus tempos de vida;\n" +
                "                                8) Passe o cursor do mouse sobre os processos na fila de entrada (Blocos Verdes) para ver seus tamanhos. ", "DICA", JOptionPane.INFORMATION_MESSAGE);
        this.jButtonStart.setEnabled(false);
        this.jButtonRestart.setEnabled(true);
        this.jPanelAnimation.setToolTipText(null);
    }//GEN-LAST:event_jButtonStartActionPerformed

    private void jButtonInsertProcessActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonInsertProcessActionPerformed
        if( (this.jTextFieldProcessSize.getText().equals("")) || ((Integer.parseInt(this.jTextFieldProcessSize.getText()) < MINIMUM_SIZE)) || ((Integer.parseInt(this.jTextFieldProcessSize.getText()) > MAXIMUM_SIZE)) ){
            JOptionPane.showMessageDialog(null, "Digite um número inteiro entre " + MINIMUM_SIZE + " e " + MAXIMUM_SIZE + " para o tamanho do processo.", "ERRO", JOptionPane.ERROR_MESSAGE);
        }
        else{
            if(this.processesQueue == null) {
                this.processesQueue = new Vector<Process>();
            }
            if(this.processesQueue.size() <= 13) { //Its size must be less than 13 because of the 'jPanelProcessQueue's' size
                Process process = new Process();
                process.setSize(Integer.parseInt(this.jTextFieldProcessSize.getText()));
                //The process' life time is equal to ((MAXIMUM_SIZE + 4) - its size);
                process.setLifeTime((MAXIMUM_SIZE + 4) - Integer.parseInt(this.jTextFieldProcessSize.getText()));
                this.processCounter++;
                process.setId(this.processCounter);
                this.processesQueue.add(process);
                this.paintProcessesQueue(this.processesQueue);
                JOptionPane.showMessageDialog(null, "Processo inserido com sucesso! \n Para adicionar e visualizar a inserção de um processo da fila de entrada na memória, clique em 'Passos do Algoritmo'.\n" +
                        "OBSERVAÇÕES: 1) Quando clicar em 'Passos do Algoritmo' os tempos de vida dos processos que estão na memória principal serão reduzidos em uma unidade;\n" +
                        "                                2) Passe o cursor do mouse sobre os processos (Blocos Vermelhos) para visualizar seus tempos de vida restantes. ", "DICA", JOptionPane.INFORMATION_MESSAGE);
                
                if(this.st != null) {
                    if(!this.st.getJButtonOkNextStep().isVisible()) {
                        this.jButtonAlgorithmSteps.setEnabled(true);
                    }    
                }
                else {
                    this.jButtonAlgorithmSteps.setEnabled(true);
                }
            }
            else {
                JOptionPane.showMessageDialog(null, "A fila de entrada de processos está cheia. \n" +
                            "DICA: Clique em 'Passos do Algoritmo' para inserir um processo desta fila na memória principal.", "ATENÇÃO", JOptionPane.WARNING_MESSAGE);
            }
        }
        this.jTextFieldProcessSize.setText("");        
    }//GEN-LAST:event_jButtonInsertProcessActionPerformed

    private void jButtonAlgorithmStepsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAlgorithmStepsActionPerformed
        if(st != null) {
            this.finalMainMemory = st.getFinalMainMemory();
            this.initialPositionBlocks = st.getInitialPositionBlocks();
        }
        st = new AlgorithmStepsThread(this, this.jButtonAlgorithmSteps, this.finalMainMemory, this.processesQueue, this.jPanelAnimation, this.initialPositionBlocks, this.jButtonOkNextStep);
        t = new Thread(st);
        t.start();
}//GEN-LAST:event_jButtonAlgorithmStepsActionPerformed

    private void jButtonRestartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRestartActionPerformed
        this.jTextFieldProcessSize.setText("");
        this.jPanelAnimation.removeAll();
        this.jPanelAnimation.repaint();
        this.jPanelProcessesQueue.removeAll();
        this.jPanelProcessesQueue.repaint();
        this.jPanelProcessesQueue.setVisible(false);
        this.jPanelInsertion.setVisible(false);
        this.jPanelLegend.setVisible(false);
        this.jButtonStart.setEnabled(true);
        this.jButtonRestart.setEnabled(false);
        this.jButtonAlgorithmSteps.setEnabled(false);
        this.mainMemory = null;
        this.finalMainMemory = null;
        this.processesQueue = null;
        this.processCounter = 0;
        this.initialPositionBlocks = 0;
        if(this.st != null) {
            this.st.getJButtonOkNextStep().setVisible(false);
            this.st = null;
        }
        if (this.t != null) {
            if (t.isAlive()) {
                t.stop();
            }    
        }
        System.gc();
    }//GEN-LAST:event_jButtonRestartActionPerformed
    
    /*
     * This method paints the processes queue (Vector<Process> processesQueue) in 'jPanelProcessesQueue'.
     */ 
    public void paintProcessesQueue(Vector<Process> processesQueue) {
        int orientationAxisY = 50;
        
        this.jPanelProcessesQueue.removeAll();
        this.jPanelProcessesQueue.repaint();
        this.jPanelProcessesQueue.add(jLabelIncreaseOrientation);
        
        for(int i = 0; i <= (processesQueue.size() - 1); i++) {
            JTextField block = new JTextField();
            block.setBackground(new java.awt.Color(0, 255, 0));
            block.setForeground(new java.awt.Color(0, 0, 0));
            block.setHorizontalAlignment(javax.swing.JTextField.CENTER);
            block.setEditable(false);
            block.setText("P" + String.valueOf(processesQueue.elementAt(i).getId()));
            block.setToolTipText("Tamanho de P" + String.valueOf(processesQueue.elementAt(i).getId()) + " = " + String.valueOf(processesQueue.elementAt(i).getSize()));
            this.jPanelProcessesQueue.add(block);
            
            if (i <= 6) {
                block.setBounds(25+(i*35), orientationAxisY - 10, 30, 30);
            }
            else {
                if (i <= 13) {
                    block.setBounds(25+((i - 7)*35), orientationAxisY + 30, 30, 30);
                }
            }
        }
    }
    
    /*
     * This method is used to paint a memory (generated by the method 'createsRandomMemory' of the class 'MemoryGenerator') in jPanelAnimation
     */
    public void paintMainMemory(Vector<MemoryCell> memory) {
        JTextField blocks;
        int orientationAxisY = 55;
        int auxSize = 0;
        boolean auxFreedom = false;
        int rowBlocks = MEMORY_SIZE / 3; //3 rows of (MEMORY_SIZE / 3) elements (blocks) each one.
        int rest = 0; //This variable stores how many blocks exceeded the row's size.
        int index = 0; //This variable is an index to the memory created by 'createsRandomMemory()' of the MemoryGenerator class.
        
        int j = 0;
        int i = 0;
        
        this.jPanelAnimation.removeAll();
        this.jPanelAnimation.repaint();
        
        // It fills the first row
        while ((rowBlocks > 0) && (index <= (memory.size() - 1))) {
            auxSize = memory.elementAt(index).getSize();
            auxFreedom = memory.elementAt(index).isIsFree();

            if(auxSize <= rowBlocks){
                j = 0;
                while(j <= (auxSize - 1)) {
                    blocks = new JTextField();
                    if(auxFreedom == false) {
                        blocks.setBackground(new java.awt.Color(255, 51, 0));
                        blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                        blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                    }
                    else {
                        blocks.setBackground(new java.awt.Color(255, 255, 255));
                    }                
                    blocks.setForeground(new java.awt.Color(0, 0, 0));
                    blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                    blocks.setEditable(false);
                    this.jPanelAnimation.add(blocks);                
                    blocks.setBounds(20+(i*35), orientationAxisY, 30, 30);
                    j += 1;
                    i += 1;
                    rowBlocks -= 1;
                }
                index += 1;
            }
            
            //This bit puts only the blocks that fit in the first row's size and stores in the variable 'rest' how many blocks it has not put in
            else {
                j = 0;
                while(j <= (rowBlocks - 1)) {
                    blocks = new JTextField();
                    if(auxFreedom == false) {
                        blocks.setBackground(new java.awt.Color(255, 51, 0));
                        blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                        blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                    }
                    else {
                        blocks.setBackground(new java.awt.Color(255, 255, 255));
                    }                
                    blocks.setForeground(new java.awt.Color(0, 0, 0));
                    blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                    blocks.setEditable(false);
                    this.jPanelAnimation.add(blocks);                
                    blocks.setBounds(20+(i*35), orientationAxisY, 30, 30);
                    j += 1;
                    i += 1;
                }
                rest = auxSize - rowBlocks;
                rowBlocks = 0;
                index += 1;
            }
        }
        
        //This bit puts the missed blocks from the first row into the second row
        int restAux = 0;
        rowBlocks = MEMORY_SIZE / 3;
        if (rest > 0) {
            restAux = rest;
            j = 0;
            i = 0;
            while((j <= rest - 1) && (rowBlocks > 0)) {
                blocks = new JTextField();
                if(auxFreedom == false) {
                    blocks.setBackground(new java.awt.Color(255, 51, 0));
                    blocks.setText("P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()));
                    blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index-1).getProcess().getLifeTime()));
                }
                else {
                    blocks.setBackground(new java.awt.Color(255, 255, 255));
                }
                blocks.setForeground(new java.awt.Color(0, 0, 0));
                blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                blocks.setEditable(false);
                this.jPanelAnimation.add(blocks);
                blocks.setBounds(20+(i*35), orientationAxisY + 60, 30, 30);
                j += 1;
                i += 1;
                rowBlocks -= 1;
                restAux -= 1;
            }
        }
        
        //This bit puts the missed blocks into the third row if they exist
        boolean flag = false;
        if ((restAux > 0) && (rowBlocks == 0)) {
            rowBlocks = MEMORY_SIZE / 3;
            flag = true;
            j = 0;
            i = 0;
            while((j <= restAux - 1) && (rowBlocks > 0)){
                blocks = new JTextField();
                if(auxFreedom == false) {
                    blocks.setBackground(new java.awt.Color(255, 51, 0));
                    blocks.setText("P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()));
                    blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index-1).getProcess().getLifeTime()));
                }
                else {
                    blocks.setBackground(new java.awt.Color(255, 255, 255));
                }
                blocks.setForeground(new java.awt.Color(0, 0, 0));
                blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                blocks.setEditable(false);
                this.jPanelAnimation.add(blocks);
                blocks.setBounds(20+(i*35), orientationAxisY + 120, 30, 30);
                j += 1;
                i += 1;
                rowBlocks -= 1;
            }
        }

        // If some cell occupied part of first row + second row + part of third row
        if(flag) {
            while((rowBlocks > 0) && (index <= (memory.size() - 1))) {
                auxSize = memory.elementAt(index).getSize();
                auxFreedom = memory.elementAt(index).isIsFree();

                if(auxSize <= rowBlocks){
                    j = 0;
                    while(j <= (auxSize - 1)) {
                        blocks = new JTextField();
                        if(auxFreedom == false) {
                            blocks.setBackground(new java.awt.Color(255, 51, 0));
                            blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                            blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                        }
                        else {
                            blocks.setBackground(new java.awt.Color(255, 255, 255));
                        }                
                        blocks.setForeground(new java.awt.Color(0, 0, 0));
                        blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                        blocks.setEditable(false);
                        this.jPanelAnimation.add(blocks);                
                        blocks.setBounds(20+(i*35), orientationAxisY + 120, 30, 30);
                        j += 1;
                        i += 1;
                        rowBlocks -= 1;
                    }
                    index += 1;    
                }
            }
        }
        // This bit fills the second row from the 'rest' position
        else {
            i = rest;
            rest = 0;

            while ((rowBlocks > 0) && (index <= (memory.size() - 1))) {
                auxSize = memory.elementAt(index).getSize();
                auxFreedom = memory.elementAt(index).isIsFree();

                if(auxSize <= rowBlocks){
                    j = 0;
                    while(j <= (auxSize - 1)) {
                        blocks = new JTextField();
                        if(auxFreedom == false) {
                            blocks.setBackground(new java.awt.Color(255, 51, 0));
                            blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                            blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                        }
                        else {
                            blocks.setBackground(new java.awt.Color(255, 255, 255));
                        }                
                        blocks.setForeground(new java.awt.Color(0, 0, 0));
                        blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                        blocks.setEditable(false);
                        this.jPanelAnimation.add(blocks);                
                        blocks.setBounds(20+(i*35), orientationAxisY + 60, 30, 30);
                        j += 1;
                        i += 1;
                        rowBlocks -= 1;
                    }
                    index += 1;    
                }

                //This bit puts only the blocks that fit in the second row's size and stores in the variable 'rest' how many blocks it has not put in
                else {
                    j = 0;
                    while(j <= (rowBlocks - 1)) {
                        blocks = new JTextField();
                        if(auxFreedom == false) {
                            blocks.setBackground(new java.awt.Color(255, 51, 0));
                            blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                            blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                        }
                        else {
                            blocks.setBackground(new java.awt.Color(255, 255, 255));
                        }                
                        blocks.setForeground(new java.awt.Color(0, 0, 0));
                        blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                        blocks.setEditable(false);
                        this.jPanelAnimation.add(blocks);                
                        blocks.setBounds(20+(i*35), orientationAxisY + 60, 30, 30);
                        j += 1;
                        i += 1;
                    }
                    rest = auxSize - rowBlocks;
                    rowBlocks = 0;
                    index += 1;
                }            
            }

            //This bit puts the missed blocks from the second row into the third row
            rowBlocks = MEMORY_SIZE / 3;
            if (rest > 0) {
                j = 0;
                i = 0;
                while(j <= rest - 1) {
                    blocks = new JTextField();
                    if(auxFreedom == false) {
                        blocks.setBackground(new java.awt.Color(255, 51, 0));
                        blocks.setText("P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()));
                        blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index-1).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index-1).getProcess().getLifeTime()));
                    }
                    else {
                        blocks.setBackground(new java.awt.Color(255, 255, 255));
                    }
                    blocks.setForeground(new java.awt.Color(0, 0, 0));
                    blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                    blocks.setEditable(false);
                    this.jPanelAnimation.add(blocks);
                    blocks.setBounds(20+(i*35), orientationAxisY + 120, 30, 30);
                    j += 1;
                    i += 1;
                    rowBlocks -= 1;
                }
            }

            i = rest;
            while ((rowBlocks > 0) && (index <= (memory.size() - 1))) {
                auxSize = memory.elementAt(index).getSize();
                auxFreedom = memory.elementAt(index).isIsFree();

                if(auxSize <= rowBlocks){
                    j = 0;
                    while(j <= (auxSize - 1)) {
                        blocks = new JTextField();
                        if(auxFreedom == false) {
                            blocks.setBackground(new java.awt.Color(255, 51, 0));
                            blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                            blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                        }
                        else {
                            blocks.setBackground(new java.awt.Color(255, 255, 255));
                        }                
                        blocks.setForeground(new java.awt.Color(0, 0, 0));
                        blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                        blocks.setEditable(false);
                        this.jPanelAnimation.add(blocks);                
                        blocks.setBounds(20+(i*35), orientationAxisY + 120, 30, 30);
                        j += 1;
                        i += 1;
                        rowBlocks -= 1;
                    }
                    index += 1;    
                }

                //This bit puts only the blocks that fit in the row's size and stores in the variable 'rest' how many blocks it has not put in
                else {
                    j = 0;
                    while(j <= (rowBlocks - 1)) {
                        blocks = new JTextField();
                        if(auxFreedom == false) {
                            blocks.setBackground(new java.awt.Color(255, 51, 0));
                            blocks.setText("P" + String.valueOf(memory.elementAt(index).getProcess().getId()));
                            blocks.setToolTipText("Tempo de vida de P" + String.valueOf(memory.elementAt(index).getProcess().getId()) + " = " + String.valueOf(memory.elementAt(index).getProcess().getLifeTime()));
                        }
                        else {
                            blocks.setBackground(new java.awt.Color(255, 255, 255));
                        }                
                        blocks.setForeground(new java.awt.Color(0, 0, 0));
                        blocks.setHorizontalAlignment(javax.swing.JTextField.CENTER);
                        blocks.setEditable(false);
                        this.jPanelAnimation.add(blocks);                
                        blocks.setBounds(20+(i*35), orientationAxisY + 120, 30, 30);
                        j += 1;
                        i += 1;
                    }
                    rest = auxSize - rowBlocks;
                    rowBlocks = 0;
                    index += 1;
                }
            }
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAlgorithmSteps;
    private javax.swing.JButton jButtonInsertProcess;
    private javax.swing.JButton jButtonIntroduction;
    private javax.swing.JButton jButtonOkNextStep;
    private javax.swing.JButton jButtonRestart;
    private javax.swing.JButton jButtonStart;
    private javax.swing.JLabel jLabelIncreaseOrientation;
    private javax.swing.JLabel jLabelProcessSize;
    private javax.swing.JPanel jPanelAlgorithm;
    private javax.swing.JPanel jPanelAnimation;
    private javax.swing.JPanel jPanelInsertion;
    private javax.swing.JPanel jPanelIntroduction;
    private javax.swing.JPanel jPanelLegend;
    private javax.swing.JPanel jPanelProcessesQueue;
    private javax.swing.JScrollPane jScrollPaneAlgorithm;
    private javax.swing.JScrollPane jScrollPaneIntroduction;
    private javax.swing.JTextArea jTextAreaAlgorithm;
    private javax.swing.JTextArea jTextAreaIntroduction;
    private javax.swing.JTextField jTextFieldLegendActiveProcess;
    private javax.swing.JTextField jTextFieldLegendBusy;
    private javax.swing.JTextField jTextFieldLegendFree;
    private javax.swing.JTextField jTextFieldLegendJ;
    private javax.swing.JTextField jTextFieldLegendProcessInTheQueue;
    private javax.swing.JTextField jTextFieldProcessSize;
    // End of variables declaration//GEN-END:variables
    
}
